package com.cwm.test.reactor;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Set;

public class Reactor implements Runnable {
        final Selector selector;
        final ServerSocketChannel serverSocketChannel;
        public static void main(String[] args) throws IOException {
                new Thread(new Reactor(1234)).start();
        }
        public Reactor(int port) throws IOException {
                selector = Selector.open();
                serverSocketChannel = ServerSocketChannel.open();
                serverSocketChannel.socket().bind(new InetSocketAddress(port));
                serverSocketChannel.configureBlocking(false);
                SelectionKey key = serverSocketChannel.register(selector,
                        SelectionKey.OP_ACCEPT);
                key.attach(new Acceptor());
        }
        @Override
        public void run() {
                while (!Thread.interrupted()) {
                        try {
                                selector.select();
                                Set<SelectionKey> selectionKeys = selector.selectedKeys();
                                for (SelectionKey selectionKey : selectionKeys) {
                                        dispatch(selectionKey);
                                }
                                selectionKeys.clear();
                        } catch (IOException e) {
                                e.printStackTrace();
                        }
                }
        }
        private void dispatch(SelectionKey selectionKey) {
                Runnable run = (Runnable) selectionKey.attachment();
                if (run != null) {
                        run.run();
                }
        }
        class Acceptor implements Runnable {
                @Override
                public void run() {
                        try {
                                SocketChannel channel = serverSocketChannel.accept();
                                if (channel != null) {
                                        new Handler(selector, channel);
                                }
                        } catch (IOException e) {
                                e.printStackTrace();
                        }
                }
        }
}

